package com.lnking.lnkingplace.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lnking.lnkingplace.Util.StringUtil;
import com.lnking.lnkingplace.Util.UserUtil;
import com.lnking.lnkingplace.mapper.InspectMapper;
import com.lnking.lnkingplace.model.dto.inspect.InspectDetailDto;
import com.lnking.lnkingplace.model.dto.inspect.InspectExportDto;
import com.lnking.lnkingplace.model.dto.inspect.InspectToPlaceDto;
import com.lnking.lnkingplace.model.dto.inspect.UserByGroup;
import com.lnking.lnkingplace.model.dto.inspect.inspectType.InspectIndexListDto;
import com.lnking.lnkingplace.model.dto.inspect.inspectType.InspectTypeByPlaceDto;
import com.lnking.lnkingplace.model.dto.rectification.RectificationResultDto;
import com.lnking.lnkingplace.model.dto.user.UserDto;
import com.lnking.lnkingplace.model.entity.*;
import com.lnking.lnkingplace.model.enums.RectificationStatus;
import com.lnking.lnkingplace.model.enums.RectificationType;
import com.lnking.lnkingplace.model.request.inspect.*;
import com.lnking.lnkingplace.model.request.place.PlaceUpdateStatusRequest;
import com.lnking.lnkingplace.service.*;
import com.lnking.starter.mybatis.entity.BaseEntity;
import com.lnking.starter.mybatis.service.impl.CustomServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author sn
 * @since 2022-08-20
 */
@Service
public class InspectServiceImpl extends CustomServiceImpl<InspectMapper, Inspect> implements IInspectService {

    /**
     * 分号隔开
     */
    public static final String SPIT=";";
    public static final String TRUE="是";
    public static final String OK="达标";
    public static final String FAIL="不达标";
    public static final String CHECK="检查";
    public static final String REVIEW="复查";
    public static final String NO="否";
    public static final String CLOSED="已停业(已沟通确认)";
    public static final String NOTOPEN="暂未营业";
    public static final String ADDRESS="地址有误";
    public static final String Noproblem="暂无问题";
    public static final String PROFESSIONAL="15123996925";

    @Autowired
    IPlaceInfoService placeInfoService;

    @Autowired
    IRectificationService rectificationService;


    @Autowired
    ILeadersService leadersService;

    @Autowired
    IUserService userService;

    @Autowired
    UserUtil userUtil;

    @Autowired
    IInspectResultService iInspectResultService;

    @Autowired
    IInspectTypeService iInspectTypeService;

    @Autowired
    IInspectGroupService iInspectGroupService;

    @Override
    public void add(InspectAddRequest params) {
        Inspect entity = new Inspect();
        BeanUtils.copyProperties(params, entity);
        UserDto user = userUtil.getUser();
        entity.setCreateTime(LocalDateTime.now());
        entity.setCreateId(user.getId());
        entity.setCreateName(user.getName());
        getBaseMapper().insert(entity);
        // 新增组
        for (String group : params.getGroupNames().split(SPIT)) {
            iInspectGroupService.insertByName(group,entity.getId());
        }

        for (String s : entity.getPlaceIds().split(SPIT)) {
            Rectification rectification=new Rectification();
            rectification.setPlaceId(s);
            rectification.setInspectId(entity.getId());
            rectification.setType(CHECK);
            rectification.setSort(0);
            rectificationService.getBaseMapper().insert(rectification);

            // 创建检查内容
            Map<String,List<InspectIndexListDto>> contents = iInspectTypeService.getContent(params.getType());
            for(String key:contents.keySet()){
                List<InspectIndexListDto> list = contents.get(key);
                for (InspectIndexListDto content : list) {
                    InspectResult inspectResult = new InspectResult();
                    inspectResult.setRectificationId(rectification.getId());
                    inspectResult.setInspectContent(content.getContent());
                    inspectResult.setInspectType(key);
                    inspectResult.setSort(content.getSort());
                    inspectResult.setHiddenDanger(content.getHiddenDanger());
                    inspectResult.setRectificationMeasures(content.getRectificationMeasures());
                    inspectResult.setCreateTime(LocalDateTime.now());
                    iInspectResultService.getBaseMapper().insert(inspectResult);
                }

            }
        }
        

    }

    @Override
    public void update(InspectUpdateRequest params) {
        Inspect entity = new Inspect();
        BeanUtils.copyProperties(params, entity);
        getBaseMapper().updateById(entity);
        // 新增组
        for (String group : params.getGroupNames().split(SPIT)) {
            InspectGroup inspectGroup = iInspectGroupService.selectByName(group, entity.getId());
            if(inspectGroup == null ){
                iInspectGroupService.insertByName(group,entity.getId());
            }
        }
    }

    @Override
    public InspectDetailDto getInspectDetailById(String id) {
        Inspect inspect =getBaseMapper().selectById(id);
        InspectDetailDto dto=new InspectDetailDto();
        List<InspectToPlaceDto> placeList =new ArrayList<>();
        BeanUtils.copyProperties(inspect, dto);

        // 检查组
        List<UserByGroup> user=new ArrayList<>();

        for (String group : dto.getGroupNames().split(SPIT)) {
            UserByGroup userByGroup = new UserByGroup();
            List<String> userNameList=new ArrayList<>();
            InspectGroup inspectGroup = iInspectGroupService.selectByName(group, inspect.getId());
            if(inspectGroup.getUserIds()!= null&&!inspectGroup.getUserIds().equals("")){
                for (String s : inspectGroup.getUserIds().split(SPIT)) {
                    Leaders place = leadersService.getById(s);
                    userNameList.add(place.getName());
                }
            }
            userByGroup.setId(inspectGroup.getId());
            userByGroup.setGroupName(group);
            userByGroup.setUserName(userNameList);
            user.add(userByGroup);
        }
        // 检查结果
        dto.setPlaceList(getResult(id));
        dto.setUserNameList(user);
        return dto;
    }

    @Override
    public void result(InspectResultByPlaceRequest  params) throws Exception {
        if(params.getList().size() ==0){
            throw new Exception("请输入指标");
        }
        // 添加检查时间
        // 拿取场所检查的id
        String rectificationId = params.getList().get(0).getRectificationId();
        Rectification rectification = rectificationService.getBaseMapper().selectById(rectificationId);
        rectification.setInspectTime(LocalDateTime.now());
        UserDto user = userUtil.getUser();
        rectification.setInspectPersonId(user.getId());
        rectification.setInspectPersonName(user.getName());
        //如果场所已停业
        if(params.getOperatingStatus().equals(CLOSED)){
            // 修改场所状态 加入修改时间
            PlaceInfo byId = placeInfoService.getById(params.getId());
            byId.setOperatingTime(LocalDateTime.now());
            byId.setOperatingStatus(params.getOperatingStatus());
            placeInfoService.updateById(byId);

            // 添加检查状态为场所状态
            rectification.setInspectResult(params.getOperatingStatus());
            rectificationService.updateById(rectification);

            // 场所暂未营业
        }else if(params.getOperatingStatus().equals(NOTOPEN)||params.getOperatingStatus().equals(Noproblem)||params.getOperatingStatus().equals(ADDRESS)){
            // 添加检查状态为场所状态
            rectification.setInspectResult(params.getOperatingStatus());
            rectificationService.updateById(rectification);
        }else{
        // 验证是否传入值
        for (InspectResult inspectResult : params.getList()) {
            if (null == inspectResult.getStatus()) {
                throw new Exception("没有选择是否");
            }
            // 设置时间
            inspectResult.setTime(LocalDateTime.now());
        }
        // 更新
        iInspectResultService.updateBatchById(params.getList());

        long ok = params.getList().stream().filter(e -> !e.getStatus().equals(TRUE)).count();
        if(ok == 0&& rectification.getInspectResult() ==null){
            // 达标
            rectification.setInspectResult(OK);
        }
        if(ok != 0&& rectification.getInspectResult() ==null){
            // 不达标
            rectification.setInspectResult(FAIL);

            // 生成复查表
            Rectification review = new Rectification();
            review.setPlaceId(rectification.getPlaceId());
            review.setInspectId(rectification.getInspectId());
            review.setSort(rectification.getSort()+1);
            review.setType(REVIEW);
            rectificationService.getBaseMapper().insert(review);

            // 创建检查内容
            List<InspectResult> byRectificationId = iInspectResultService.getByRectificationId(rectification.getId());
            List<InspectResult> inspectResultList =new ArrayList<>();
            // 替换整改id
            for (InspectResult inspectResult : byRectificationId.stream().filter(e-> NO.equals(e.getStatus())).collect(Collectors.toList())) {
                inspectResult.setId(null);
                inspectResult.setStatus(null);
                inspectResult.setTime(LocalDateTime.now());
                inspectResult.setRectificationId(review.getId());
                inspectResult.setCreateTime(LocalDateTime.now());
                inspectResultList.add(inspectResult);
            }
            // 批量添加
            iInspectResultService.saveBatch(inspectResultList);
        }
            rectificationService.updateById(rectification);
        }

    }

    @Override
    public InspectTypeByPlaceDto getResultList(InspectResultRequest params) throws Exception {
        PlaceInfo placeInfo = placeInfoService.getById(params.getPlaceId());
        InspectTypeByPlaceDto inspectTypeByPlaceDto = new InspectTypeByPlaceDto();
        inspectTypeByPlaceDto.setPlaceName(placeInfo.getPlaceName());
        inspectTypeByPlaceDto.setPlaceId(placeInfo.getId());
        List<InspectResult> resultList = iInspectResultService.getResultList(params);
        Rectification lastRecord = rectificationService.getLastRecord(params.getPlaceId(), params.getInspectId());
        String rectificationId = lastRecord.getId();
        inspectTypeByPlaceDto.setRectificationId(rectificationId);


        if(StringUtils.isNotBlank(params.getStatus())){
            //判断是否为第一次检查 是的话整改为空
            Rectification byId = rectificationService.getById(rectificationId);
            if (byId.getType().equals(CHECK)){
                inspectTypeByPlaceDto.setInspectResultList(new ArrayList<>());
            }else {
                List<InspectResult> list = new ArrayList<>();
                for (InspectResult inspectResult : resultList) {
                    if (StringUtils.isNotBlank(inspectResult.getStatus())) {
                        if (inspectResult.getStatus().equals(params.getStatus())) {
                            list.add(inspectResult);
                        }
                    } else {
                        list.add(inspectResult);
                    }
                }
                inspectTypeByPlaceDto.setInspectResultList(list);
            }
        }else{
            inspectTypeByPlaceDto.setInspectResultList(resultList);
        }


        return inspectTypeByPlaceDto;
    }

    @Override
    public List<InspectExportDto> export(InspectExportRequest params) {
        return getBaseMapper().export(params);
    }

    @Override
    public  List<InspectToPlaceDto>  getResult(String id) {
        List<InspectToPlaceDto> placeList =new ArrayList<>();
        Inspect inspect =getBaseMapper().selectById(id);
        // 检查结果
        for (String placeId : inspect.getPlaceIds().split(SPIT)) {
            // 检查记录
            // place
            InspectToPlaceDto placeDto =new InspectToPlaceDto();
            PlaceInfo placeInfo =null;
            placeInfo = placeInfoService.getById(placeId);
            if(placeInfo != null){
                // Rectification
                QueryWrapper<Rectification> wapper=new QueryWrapper<>();
                wapper.lambda().eq(Rectification::getPlaceId,placeId);
                wapper.lambda().eq(Rectification::getInspectId,inspect.getId());
                wapper.lambda().eq(Rectification::getDelFlag,false);
                wapper.lambda().eq(Rectification::getType,CHECK);
                Rectification rectification = rectificationService.getBaseMapper().selectOne(wapper);
                BeanUtils.copyProperties(placeInfo, placeDto);
                BeanUtils.copyProperties(rectification, placeDto);
                // inspectResultList
                if(placeDto.getInspectTime() != null){
                    List<InspectResult> inspectResultList = iInspectResultService.getByRectificationId(rectification.getId());
                    placeDto.setInspectResultList(inspectResultList);

                    // RectificationResultDto 整体情况
                    List<RectificationResultDto> result = rectificationService.getResult(inspect.getId(), placeId);
                    placeDto.setRectificationResultDtoList(result);
                }
            }
            placeList.add(placeDto);

        }
        return placeList;
    }

    @Override
    public InspectToPlaceDto getResultDetails( String inspectId  ,String placeId) {
        // place
        InspectToPlaceDto placeDto =new InspectToPlaceDto();
        PlaceInfo place = placeInfoService.getById(placeId);
        // Rectification
        QueryWrapper<Rectification> wapper=new QueryWrapper<>();
        wapper.lambda().eq(Rectification::getPlaceId,placeId);
        wapper.lambda().eq(Rectification::getInspectId,inspectId);
        wapper.lambda().eq(Rectification::getDelFlag,false);
        wapper.lambda().eq(Rectification::getType,CHECK);
        Rectification rectification = rectificationService.getBaseMapper().selectOne(wapper);
        BeanUtils.copyProperties(place, placeDto);
        BeanUtils.copyProperties(rectification, placeDto);
        // inspectResultList
        if(placeDto.getInspectTime() != null){
            List<InspectResult> inspectResultList = iInspectResultService.getByRectificationId(rectification.getId());
            placeDto.setInspectResultList(inspectResultList);

            // RectificationResultDto 整体情况
            List<RectificationResultDto> result = rectificationService.getResult(inspectId, placeId);
            placeDto.setRectificationResultDtoList(result);
        }
        return placeDto;
    }

    /**
     *
     * @param id
     * @return
     */
    @Override
    public List<InspectToPlaceDto> getReview(String id) {
        List<InspectToPlaceDto> placeList =new ArrayList<>();
        Inspect inspect =getBaseMapper().selectById(id);
        // 检查结果
        for (String placeId : inspect.getPlaceIds().split(SPIT)) {
            // 检查记录

            // Rectification
            Rectification rectification = rectificationService.getReview(placeId,inspect.getId());
            // 如果没有待复查状态的就跳过该place
            if (rectification == null){
                continue;
            }
            // place
            InspectToPlaceDto placeDto =new InspectToPlaceDto();
            PlaceInfo place = placeInfoService.getById(placeId);

            BeanUtils.copyProperties(place, placeDto);
            BeanUtils.copyProperties(rectification, placeDto);
            placeList.add(placeDto);
    }
        return  placeList;
    }

    @Override
    public void addIndexByLibrary( IndexByLibraryRequest params) {
        for (String inspectTypeId : params.getInspectTypeIds()) {
            InspectType inspectType = iInspectTypeService.getBaseMapper().selectById(inspectTypeId);
            InspectResult inspectResult = new InspectResult();
            inspectResult.setRectificationId(params.getRectificationId());
            inspectResult.setInspectContent(inspectType.getContent());
            inspectResult.setInspectType(inspectType.getType());
            inspectResult.setHiddenDanger(inspectType.getHiddenDanger());
            inspectResult.setRectificationMeasures(inspectType.getRectificationMeasures());
            inspectResult.setCreateTime(LocalDateTime.now());
            iInspectResultService.getBaseMapper().insert(inspectResult);
        }

    }

    @Override
    public void addIndexByWriter(AddIndexRequest params) {
        InspectResult inspectResult = new InspectResult();
        BeanUtils.copyProperties(params,inspectResult);
        inspectResult.setCreateTime(LocalDateTime.now());
        inspectResult.setInspectContent(params.getContent());
        // 根据登陆人电话号码判断是否为专业人员直接录入到指标库
        UserDto user = userUtil.getUser();
        String desensitizationPhone = user.getDesensitizationPhone();
        if (desensitizationPhone.equals(PROFESSIONAL)) {
            InspectType inspectType = new InspectType();
            BeanUtils.copyProperties(params,inspectType);
            inspectType.setCreateTime(LocalDateTime.now());
            inspectType.setType(params.getInspectType());
            iInspectTypeService.save(inspectType);
        }
        iInspectResultService.getBaseMapper().insert(inspectResult);
    }

    @Override
    public void updateResult(List<InspectResult> params) throws Exception {
        // 验证是否传入值
        for (InspectResult inspectResult : params) {
            if (null == inspectResult.getStatus()) {
                throw new Exception("没有选择是否");
            }
            // 如果新加了指标 就设置时间
            if (inspectResult.getTime() == null){
                inspectResult.setTime(LocalDateTime.now());
            }

        }

        // 添加检查时间
        // 拿取场所检查的id
        String rectificationId = params.get(0).getRectificationId();
        Rectification rectification = rectificationService.getBaseMapper().selectById(rectificationId);
        // 获取检查后的第一次复查
        Rectification rect=rectificationService.getAfterInspect(rectification.getInspectId(),rectification.getPlaceId());
        List<String> collect =null;
        if(rect!=null){
            // 获取复查结果
            List<InspectResult> inspectResults = iInspectResultService.getByRectificationId(rect.getId());
            // 如果检查结果已被场所确认 则不允许对该条信息进行修改，返回提示
            // 获取复查后的检查列表且为检查后的
             collect = inspectResults.stream().filter(e -> e.getPlaceContent() != null).map(e -> e.getInspectContent()).collect(Collectors.toList());
            // 本次修改内容是否在其中
            if (collect.containsAll(params.stream().map(e->e.getInspectContent()).collect(Collectors.toList()))) {
                throw new Exception("场所已整改");
            }
        }
        // 更新
        iInspectResultService.updateBatchById(params);

        rectification.setInspectTime(LocalDateTime.now());
        List<InspectResult> byRectificationId = iInspectResultService.getByRectificationId(rectification.getId());
        // 获取检查结果错误的去除掉复查中场所确认剩下的结果数据
        List<InspectResult>  reviewList=new ArrayList<>();
        if(rect!=null){
            for (InspectResult inspectResult : byRectificationId) {
                if(!collect.contains(inspectResult.getInspectContent())){
                    reviewList.add(inspectResult);
                }
            }
        }else{
            reviewList=byRectificationId;
        }


        long ok = byRectificationId.stream().filter(e -> !e.getStatus().equals(TRUE)).count();

        // 创建检查内容

        List<InspectResult> inspectResultList =new ArrayList<>();

        if(ok == 0){
            // 达标
            rectification.setInspectResult(OK);
            // 查询之前是否生成复查表，删除复查表，删除复查表对应结果
            // 生成了复查表
            if (rect !=null){
                // 删除检查表
                List<InspectResult> inspectResults = iInspectResultService.getByRectificationId(rect.getId());
                rectificationService.getBaseMapper().deleteById(rect.getId());
                // 删除检查结果
                iInspectResultService.getBaseMapper().deleteBatchIds(inspectResults.stream().map(BaseEntity::getId).collect(Collectors.toList()));
            }
        }
        if(ok != 0){
            // 不达标
            rectification.setInspectResult(FAIL);
            // 查询之前是否生成复查表，有的话 修改复查结果信息，如果场所整改了就不允许修改
            // 生成了复查表
            if (rect !=null){
                // 添加检查结果
                List<InspectResult> inspectResults = iInspectResultService.getByRectificationId(rect.getId());
                List<InspectResult> collectFilter = inspectResults.stream().filter(e -> e.getPlaceContent() == null).collect(Collectors.toList());
                if(!collectFilter.equals(new ArrayList<>())){
                    iInspectResultService.getBaseMapper().deleteBatchIds(collectFilter.stream().map(BaseEntity::getId).collect(Collectors.toList()));
                }

                // 添加新的检查结果
            }else{
                // 没有就走正常逻辑
                // 生成复查表
                rect =new Rectification();
                rect.setPlaceId(rectification.getPlaceId());
                rect.setInspectId(rectification.getInspectId());
                rect.setSort(rectification.getSort()+1);
                rect.setType(REVIEW);
                rectificationService.getBaseMapper().insert(rect);
            }
            // 替换整改id
            for (InspectResult inspectResult : reviewList.stream().filter(e-> NO.equals(e.getStatus())).collect(Collectors.toList())) {
                inspectResult.setId(null);
                inspectResult.setStatus(null);
                inspectResult.setTime(LocalDateTime.now());
                inspectResult.setRectificationId(rect.getId());
                inspectResult.setCreateTime(LocalDateTime.now());
                inspectResultList.add(inspectResult);
            }
            // 批量添加
            iInspectResultService.saveBatch(inspectResultList);
        }
        rectificationService.updateById(rectification);
    }

    @Override
    public void delIndex(String inspectResultId) {
        iInspectResultService.getBaseMapper().deleteById(inspectResultId);
    }

    @Override
    public void placeAdd(InspectAddPlaceRequest params) {
        Inspect inspect = getBaseMapper().selectById(params.getInspectId());
            // 原先方案里面placeIds做比较
            List<String> collect = Arrays.stream(params.getPlaceIds().split(SPIT)).collect(Collectors.toList());
            collect.removeIf(Objects::isNull);
            List<String> collectLast = Arrays.stream(inspect.getPlaceIds().split(SPIT)).collect(Collectors.toList());
            collectLast.removeIf(Objects::isNull);
            for (String placeId : collectLast) {
                if(StringUtils.isBlank(placeId)){
                    break;
                }
                // 1.如果原先的方案里面里面有 新增没有 就是删除这个场所
                if (!collect.contains(placeId)) {
                    // 删除先去查询是否可以删除 如果已经检查就不允许删除 并返回报错
                    Rectification check = rectificationService.getCheck(inspect.getId(), placeId);
                    Assert.isNull(check.getInspectResult(), "已经检查了不可删除");
                    List<InspectResult> byRectificationId = iInspectResultService.getByRectificationId(check.getId());
                    rectificationService.getBaseMapper().deleteById(check.getId());
                    List<String> collectId = byRectificationId.stream().map(BaseEntity::getId).collect(Collectors.toList());
                    if(!collectId.equals(new ArrayList<>())){
                        iInspectResultService.getBaseMapper().deleteBatchIds(collectId);
                    }
                                    }
                // 2.如果原先的方案里面有 新增里面也有 就保持不动
            }

            for (String newPlaceId : collect) {
                // 3.如果原先的方案里面没有  新增里面有 就添加
                if (!collectLast.contains(newPlaceId)) {
                    Rectification rectification = new Rectification();
                    rectification.setPlaceId(newPlaceId);
                    rectification.setInspectId(params.getInspectId());
                    rectification.setType(CHECK);
                    rectification.setSort(0);
                    rectificationService.getBaseMapper().insert(rectification);

                    // 创建检查内容
                    Map<String, List<InspectIndexListDto>> contents = iInspectTypeService.getContent(inspect.getType());
                    for (String key : contents.keySet()) {
                        List<InspectIndexListDto> list = contents.get(key);
                        for (InspectIndexListDto content : list) {
                            InspectResult inspectResult = new InspectResult();
                            inspectResult.setRectificationId(rectification.getId());
                            inspectResult.setInspectContent(content.getContent());
                            inspectResult.setSort(content.getSort());
                            inspectResult.setHiddenDanger(content.getHiddenDanger());
                            inspectResult.setRectificationMeasures(content.getRectificationMeasures());
                            inspectResult.setInspectType(key);
                            inspectResult.setCreateTime(LocalDateTime.now());
                            iInspectResultService.getBaseMapper().insert(inspectResult);
                        }

                    }

                }
            }
            inspect.setPlaceIds(params.getPlaceIds());
            getBaseMapper().updateById(inspect);

    }

    @Override
    public void delete(String id) {
        Inspect inspect = getBaseMapper().selectById(id);
        for (String placeId : inspect.getPlaceIds().split(SPIT)) {
            // 删除整改
            List<RectificationResultDto> result = rectificationService.getResult(inspect.getId(), placeId);
            if (result.size()!=0){
                rectificationService.getBaseMapper().deleteBatchIds(result.stream().map(RectificationResultDto::getId).collect(Collectors.toList()));
            }
            // 删除整改对应结果
            for (RectificationResultDto rectificationResultDto : result) {
                List<InspectResult> byRectificationId = iInspectResultService.getByRectificationId(rectificationResultDto.getId());
                if(byRectificationId.size()!=0){
                    iInspectResultService.getBaseMapper().deleteBatchIds(byRectificationId.stream().map(BaseEntity::getId).collect(Collectors.toList()));

                }

            }
        }

        getBaseMapper().deleteById(id);

    }

    @Override
    public void photos(InspectPhotosRequest params) {
        Inspect inspect =new Inspect();
        inspect.setId(params.getInspectId());
        inspect.setPhotos(params.getPhotos());
         updateById(inspect);
    }
}
